﻿
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading.Tasks;

using FreeSql;
using Kalman;
using Newtonsoft.Json.Linq;
using Kalman.Extensions;
using System.Security.Cryptography;
using TencentCloud.Kms.V20190118.Models;

namespace QuDao
{
    /// <summary>
    /// 每日销售统计业务对象（处理数据表biz_sales_daily相关的业务逻辑）
    /// </summary>
    public sealed partial class SalesDailyBO : SingletonBase<SalesDailyBO>
    {
        readonly IFreeSql fsql;
        public SalesDailyBO() : base()
        {
            fsql = ServiceLocator.Instance.GetRequiredService<IFreeSql>();
        }
        
        /// <summary>
        /// 获取每日销售统计
        /// </summary>
        /// <param name="id">主键ID的值</param>
        /// <returns></returns>
        public T GetItem<T>(long id)
        {
        	if (id <= 0) return default;
            var item = fsql.Select<SalesDaily>().Where(a => a.ID == id).ToOne<T>();
            return item;
        }
        
        public SalesDaily GetItem(long id)
        {
        	return GetItem<SalesDaily>(id);
        }
        
        /// <summary>
        /// 获取代理每日销售统计详情
        /// </summary>
        public SalesDaily GetItem(long agentID, DateTime date)
        {
            var item = fsql.Select<SalesDaily>()
                .Where(a => a.AgentID == agentID && a.SalesDate == date.Date)
                .ToOne<SalesDaily>();
            return item;
        }

        /// <summary>
        /// 获取每日销售统计数据列表
        /// </summary>
        /// <param name="agentID">代理ID</param>
        /// <param name="beginDate">查询开始日期</param>
        /// <param name="endDate">查询结束日期</param>
        /// <param name="pageIndex">页索引，从1开始</param>
        /// <param name="pageSize">每页记录数，默认10</param>
        /// <returns></returns>
        public List<T> GetListByAgent<T>(long agentID, DateTime beginDate, DateTime endDate, int pageIndex = 1, int pageSize = 10)
        {
            var list = fsql.Select<SalesDaily>()
                .Where(a => a.AgentID == agentID && a.SalesDate >= beginDate.Date && a.SalesDate <= endDate.Date)
                .Page(pageIndex, pageSize).ToList<T>();
            return list;
        }

        /// <summary>
        /// 获取每日销售统计数据列表
        /// </summary>
        /// <param name="pid">租户ID</param>
        /// <param name="beginDate">查询开始日期</param>
        /// <param name="endDate">查询结束日期</param>
        /// <param name="pageIndex">页索引，从1开始</param>
        /// <param name="pageSize">每页记录数，默认10</param>
        /// <returns></returns>
        public List<T> GetListByPartner<T>(int tid, DateTime beginDate, DateTime endDate, int pageIndex = 1, int pageSize = 10)
        {
            var list = fsql.Select<SalesDaily>()
                .Where(a => a.TID == tid && a.SalesDate >= beginDate.Date && a.SalesDate <= endDate.Date)
                .Page(pageIndex, pageSize).ToList<T>();
            return list;
        }

        /// <summary>
        /// 删除每日销售统计数据
        /// </summary>
        /// <returns>返回影响行数</returns>
        public int Delete(long[] ids)
        {
        	if (ids == null || ids.Length == 0) return 0;
        	return fsql.Delete<SalesDaily>().Where(a => ids.Contains(a.ID)).ExecuteAffrows();
        }
        
        /// <summary>
        /// 删除每日销售统计数据
        /// </summary>
        /// <returns>返回影响行数</returns>
        public int Delete(long id)
        {
        	return fsql.Delete<SalesDaily>(id).ExecuteAffrows();
        }
        
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="req">分页查询请求对象</param>
        public PagingResult<SalesDaily> Query(PagingRequest req, int tid, long agentID, DateTime? beginDate, DateTime? endDate)
        {
        	if (req == null) throw new AppException("查询数据不能为空");
        	
            var select = fsql.Select<SalesDaily>()
                .WhereIf(tid > 0, a => a.TID == tid)
                .WhereIf(agentID > 0, a => a.AgentID == agentID)
                .WhereIf(beginDate != null, a => a.SalesDate >= beginDate)
                .WhereIf(endDate != null, a => a.SalesDate <= endDate);

            //foreach (var item in req.FilterItems)
            //{
            //    switch (item.Field)
            //    {
            //        case "AgentID":
            //            select.Where(a => a.AgentID == long.Parse(item.Value));
            //            break;
            //        //case "SalesDailyName":
            //        //    select.Where(a => a.SalesDailyName.Contains(item.Value));
            //        //    break;
            //        default:
            //            break;
            //    }
            //}

            if (!string.IsNullOrEmpty(req.SortExp))
            {
                select.OrderBy(req.SortExp);//自定义排序
            }
            else
            {
                select.OrderByDescending(a => a.ID);//默认排序
            }

            //var sql = select.ToSql();

            var list = select.Count(out var total).Page(req.PageIndex, req.PageSize).ToList<SalesDaily>();
            return new PagingResult<SalesDaily>
            {
                PageIndex = req.PageIndex,
                PageSize = req.PageSize,
                Data = list,
                Total = (int)total
            };
        }

        /// <summary>
        /// 获取代理月汇总数据（订单总数，订单总金额）
        /// </summary>
        /// <param name="agentID">代理ID</param>
        /// <param name="date"></param>
        /// <returns></returns>
        public Tuple<int, decimal> GetSummaryByMonth(long agentID, DateTime date)
        {
            var minDate = date.GetFirstDay();
            var maxDate = date.GetLastDay();
            //var select = fsql.Select<SalesDaily>()
            //    .Where(a => a.AgentID == agentID && a.SalesDate >= minDate && a.SalesDate <= maxDate);
            //var num = (int)select.Count();
            //var amount = select.Sum(a => a.Amount);

            //return new Tuple<int, decimal>(num, amount);

            var result = fsql.Select<SalesDaily>()
                .Where(a => a.AgentID == agentID && a.SalesDate >= minDate && a.SalesDate <= maxDate)
                .ToAggregate(a => new { Num = a.Sum(a.Key.OrderNum), Amount = a.Sum(a.Key.Amount) });

            return new Tuple<int, decimal>((int)result.Num, result.Amount);
        }

        /// <summary>
        /// 获取租户月汇总数据（订单总数，订单总金额，余额抵扣总金额）
        /// </summary>
        /// <param name="tid">租户ID</param>
        /// <param name="date"></param>
        /// <returns></returns>
        public Tuple<int, decimal, decimal, decimal> GetSummaryByMonth(int tid, DateTime date)
        {
            var minDate = date.GetFirstDay();
            var maxDate = date.GetLastDay();
            //var select = fsql.Select<SalesDaily>()
            //    .Where(a => a.TID == tid && a.SalesDate >= minDate && a.SalesDate <= maxDate);
            //var num = (int)select.Count();
            //var amount = select.Sum(a => a.Amount);

            //return new Tuple<int, decimal>(num, amount);

            var result = fsql.Select<SalesDaily>()
                .Where(a => a.TID == tid && a.SalesDate >= minDate && a.SalesDate <= maxDate)
                .ToAggregate(a => new { 
                    Num = a.Sum(a.Key.OrderNum), 
                    Amount = a.Sum(a.Key.Amount),
                    DividedAmount = a.Sum(a.Key.DividedAmount),
                    DeductionAmount = a.Sum(a.Key.DeductionAmount) });

            return new Tuple<int, decimal, decimal, decimal>((int)result.Num, result.Amount, result.DividedAmount, result.DeductionAmount);
        }

        /// <summary>
        /// 获取租户日汇总数据（订单总数，订单总金额）
        /// </summary>
        /// <param name="tid">租户ID</param>
        /// <param name="date"></param>
        /// <returns></returns>
        public Tuple<int, decimal> GetSummaryByDay(int tid, DateTime date)
        {
            //var select = fsql.Select<SalesDaily>()
            //    .Where(a => a.TID == tid && a.SalesDate == date.Date);
            //var num = (int)select.Count();
            //var amount = select.Sum(a => a.Amount);

            var result = fsql.Select<Order>()
                .Where(a => a.TID == tid && a.TransferDate == date.Date && a.Status >= 20) //按转账日期算
                .ToAggregate(a => new { Num = a.Count(), Amount = a.Sum(a.Key.Amount) });
            
            return new Tuple<int, decimal>((int)result.Num, result.Amount);
        }

        /// <summary>
        /// 获取团队业绩汇总数据列表（按天统计）
        /// </summary>
        /// <param name="tid">租户ID</param>
        /// <param name="agentID">代理ID</param>
        /// <param name="beginDate">开始日期</param>
        /// <param name="endDate">结束日期</param>
        /// <returns></returns>
        public List<SummaryOfDailyDto> GetSummaryListOfDaily(int tid, long agentID, DateTime beginDate, DateTime endDate)
        {
            var tenant = TenantBO.Instance.GetItem(tid) ?? throw new AppException($"无效的应用：{tid}");
            var agent = UserBO.Instance.GetItem(agentID) ?? throw new AppException($"代理用户不存在：{agentID}");
            var select = fsql.Select<SalesDaily>().Where(a => a.TID ==tid && a.SalesDate >= beginDate && a.SalesDate <= endDate);

            if(tenant.CommissionFlag == 1)
            {
                select.Where(a => a.AgentID == agentID);
            }
            else if(tenant.CommissionFlag == 2)
            {
                select.Where(a => a.AreaID == agent.AgentAreaID);
            }

            var list = select.GroupBy(a => new { StatDate = a.SalesDate.ToString("yyyy-MM-dd") })
                .ToList(a => new SummaryOfDailyDto { StatDate = a.Key.StatDate, OrderNum = (int)a.Sum(a.Value.OrderNum), OrderAmount = a.Sum(a.Value.Amount) });
            return list;
        }

        /// <summary>
        /// 获取团队业绩汇总数据列表（按月统计）
        /// </summary>
        /// <param name="tid">租户ID</param>
        /// <param name="agentID">代理ID</param>
        /// <param name="beginDate">开始日期（可以传开始月份的任意一天）</param>
        /// <param name="endDate">结束日期（可以传结束月份的任意一天）</param>
        /// <returns></returns>
        public List<SummaryOfMonthDto> GetSummaryListOfMonth(int tid, long agentID, DateTime beginDate, DateTime endDate)
        {
            var tenant = TenantBO.Instance.GetItem(tid) ?? throw new AppException($"无效的应用：{tid}");
            var agent = UserBO.Instance.GetItem(agentID) ?? throw new AppException($"代理用户不存在：{agentID}");

            var minDate = beginDate.GetFirstDay();
            var maxDate = endDate.GetLastDay();
            var select = fsql.Select<SalesDaily>().Where(a => a.TID == tid && a.SalesDate >= minDate && a.SalesDate <= maxDate);

            if (tenant.CommissionFlag == 1)
            {
                select.Where(a => a.AgentID == agentID);
            }
            else if (tenant.CommissionFlag == 2)
            {
                select.Where(a => a.AreaID == agent.AgentAreaID);
            }

            var list = select.GroupBy(a => new { Month = a.SalesDate.ToString("yyyy-MM") })
                .ToList(a => new SummaryOfMonthDto { Month = a.Key.Month, OrderNum = (int)a.Sum(a.Value.OrderNum), OrderAmount = a.Sum(a.Value.Amount) });
            return list;
        }

    }
}
